﻿package com.tomvian.twodee.common.interactions 
{
	import flash.display.DisplayObject;
	import com.tomvian.twodee.common.interactions.Interaction;
	import com.tomvian.maths.Vector2D;
	
	/**
	 * Walls
	 * @author Thomas Vian
	 */
	public class Walls extends Interaction
	{
		//--------------------------------------------------------------------------
		//
		//  Properties
		//
		//--------------------------------------------------------------------------
		
		private var _normal:Vector2D;
		private var _tangent:Vector2D;
		private var _pushOut:Vector2D;
		private var _grip:Vector2D;
		
		private var _testGripPoint:Vector2D;
		
		//--------------------------------------------------------------------------
		//
		//  Getters / Setters
		//
		//--------------------------------------------------------------------------
		
		//--------------------------------------------------------------------------
		//
		//  Constructor
		//
		//--------------------------------------------------------------------------
		
		public function Walls(walls:Array, normal:Vector2D, actorEdge:Vector2D = null, grip:Number = 0) 
		{
			super(walls, actorEdge);
			
			_normal = 	normal.normalisedMod();
			_tangent = 	normal.normal();
			_pushOut = 	normal.multiply(0.1);
			_grip = 	normal.multiply( -grip);
			
			_testGripPoint = new Vector2D();
		}
		
		//--------------------------------------------------------------------------
		//
		//  Methods
		//
		//--------------------------------------------------------------------------
		
		override public function interact():void 
		{
			if (enabled)
			{
				_testPoint.copy(actorMass.position);
				_testPoint.addMod(cameraOffset).addMod(actorMass.velocity).addMod(interactionPoint);
				
				wasInteracting = interacting;
				interacting = false;
				
				var wallClip:DisplayObject;
				var i:uint, l:uint = interactiveObjects.length;
				
				for (i = 0; i < l; i++)
				{
					wallClip = interactiveObjects[i];
					
					if (wallClip.hitTestPoint(_testPoint.x, _testPoint.y, true)) 
					{
						interacting = true;
						_testPoint.addMod(_pushOut);
						while (wallClip.hitTestPoint(_testPoint.x, _testPoint.y, true)) _testPoint.addMod(_pushOut);
					}
				}
				
				if (!interacting && wasInteracting) 
				{
					_testGripPoint.copy(_testPoint);
					_testGripPoint.addMod(_grip);
					
					for (i = 0; i < l; i++)
					{
						wallClip = interactiveObjects[i];
						
						if (wallClip.hitTestPoint(_testGripPoint.x, _testGripPoint.y, true))
						{
							interacting = true;
							_testPoint.subtractMod(_pushOut);
							while (!wallClip.hitTestPoint(_testPoint.x, _testPoint.y, true)) _testPoint.subtractMod(_pushOut);
							break;
						}
					}
				}
				
				if (interacting) 
				{
					if (actorMass.velocity.dotProduct(_normal) < 0)
					{
						var dot:Number = _tangent.dotProduct(actorMass.velocity);
						actorMass.velocity = _tangent;
						actorMass.velocity.multiplyMod(dot);
					}
				}
				
				actorMass.position = _testPoint.subtractMod(cameraOffset).subtractMod(actorMass.velocity).subtractMod(interactionPoint);
			}
		}
	}
}